/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package br.com.foxline.clinicplus.manager;

import br.com.foxline.clinicplus.entity.*;
import br.com.foxline.clinicplus.enums.DiarySituation;
import br.com.foxline.clinicplus.enums.FatorAtividadeFisica;
import br.com.foxline.clinicplus.enums.Gender;
import br.com.foxline.clinicplus.enums.ImcClassificacao;
import br.com.foxline.clinicplus.service.AnnexService;
import br.com.foxline.clinicplus.service.CustomerService;
import br.com.foxline.clinicplus.service.DiaryService;
import br.com.foxline.clinicplus.service.DoctorService;
import br.com.foxline.clinicplus.service.ProcedureService;
import br.com.foxline.clinicplus.service.RecordsService;
import br.com.foxline.clinicplus.service.SystemUserService;
import br.com.foxline.clinicplus.service.WaitingLineService;
import br.com.foxline.clinicplus.util.Msg;
import java.io.IOException;
import java.io.InputStream;
import java.io.Serializable;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import javax.annotation.PostConstruct;
import javax.ejb.EJB;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.faces.context.FacesContext;
import javax.faces.model.SelectItem;
import org.primefaces.component.tabview.TabView;
import org.primefaces.context.RequestContext;
import org.primefaces.event.FileUploadEvent;

/**
 *
 * @author roniere
 */
@ManagedBean
@ViewScoped
public class ManagerRecords implements Serializable {

    @EJB
    DiaryService diaryService;
    @EJB
    private CustomerService customerService;
    @EJB
    private RecordsService recordsService;
    @EJB
    private AnnexService annexService;
    @EJB
    private ProcedureService procedureService;
    @EJB
    private DoctorService doctorService;
    @EJB
    private WaitingLineService waitingLineService;
    @EJB
    SystemUserService systemUserService;
    private Doctor doctor;
    private Procedure procedure;
    private Diagnostic diagnostic;
    private Customer customer;
    private Evolution evolution;
    private List<Evolution> evolutions;
    private Records records;
    private Anamnese anamnese;
    private PhysicalExamination physicalExamination;
    private List<Annex> annexs;
    private List<Anamnese> anamneses;
    private List<Records> recordses;
    private TabView tabView;
    private Diary diary;
    private String diarywaitinglineid;

    @PostConstruct
    public void init() {
        Map<String, String> params = FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap();
        String customerid = params.get("c");
        String procedureid = params.get("p");
        String doctorid = params.get("d");
        String waitinglineid = params.get("w");

        String retorno = params.get("r");
        String editar = params.get("re");

        diarywaitinglineid = params.get("dw");

        if (waitinglineid != null) {
            try {
                waitingLineService.setWaitingLine(Long.parseLong(waitinglineid));
            } catch (Exception e) {
                e.printStackTrace();
            }
        }


        customer = new Customer();
        tabView = new TabView();

        if (doctorid != null) {
            try {
                doctor = doctorService.find(Long.parseLong(doctorid));
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        if (customerid != null) {
            try {
                customer = customerService.find(Long.parseLong(customerid));
                getHistoryRecords();
            } catch (Exception e) {
                Msg.messagemError("Paciente não encontrado !");
                e.printStackTrace();
            }

            if (procedureid != null && !procedureid.equals("null")) {
                try {
                    procedure = procedureService.find(Long.parseLong(procedureid));
                } catch (Exception e) {
                    e.printStackTrace();
                    procedure = new Procedure();
                }
            } else {
                procedure = new Procedure();
            }

            if (retorno != null && !retorno.equals("") && !retorno.equals("null")) {
                tabView.setActiveIndex(5);
                try {
                    records = recordsService.find(Long.parseLong(retorno));

                    anamneses = records.getAnamneses() != null ? records.getAnamneses() : new ArrayList<Anamnese>();
                    anamnese = anamneses.isEmpty() ? new Anamnese() : anamneses.get(anamneses.size() - 1);

                    physicalExamination = records.getPhysicalExamination() != null ? records.getPhysicalExamination() : new PhysicalExamination();
                    diagnostic = records.getDiagnostic() != null ? records.getDiagnostic() : new Diagnostic();
                    annexs = records.getAnnexs() != null ? records.getAnnexs() : new ArrayList<Annex>();

                    evolutions = records.getEvolutions() != null ? records.getEvolutions() : new ArrayList<Evolution>();
                    //evolution = !evolutions.isEmpty() ? evolutions.get(0) : new Evolution();
                    evolution = new Evolution();

                } catch (Exception e) {
                    e.printStackTrace();
                    records = new Records();
                }

            } else if (editar != null && !editar.equals("") && !editar.equals("null")) {
                tabView.setActiveIndex(1);
                try {
                    records = recordsService.find(Long.parseLong(editar));

                    anamneses = records.getAnamneses() != null ? records.getAnamneses() : new ArrayList<Anamnese>();
                    anamnese = anamneses.isEmpty() ? new Anamnese() : anamneses.get(anamneses.size() - 1);

                    physicalExamination = records.getPhysicalExamination() != null ? records.getPhysicalExamination() : new PhysicalExamination();
                    diagnostic = records.getDiagnostic() != null ? records.getDiagnostic() : new Diagnostic();
                    annexs = records.getAnnexs() != null ? records.getAnnexs() : new ArrayList<Annex>();

                    evolutions = records.getEvolutions() != null ? records.getEvolutions() : new ArrayList<Evolution>();
                    //evolution = !evolutions.isEmpty() ? evolutions.get(0) : new Evolution();
                    evolution = new Evolution();

                } catch (Exception e) {
                    e.printStackTrace();
                    records = new Records();
                }

            } else {
                records = new Records();

                anamnese = new Anamnese();
                physicalExamination = new PhysicalExamination();
                diagnostic = new Diagnostic();
                annexs = new ArrayList<Annex>();
                evolution = new Evolution();
                evolutions = new ArrayList<Evolution>();

                records.setProcedure(procedure);
                if (doctor != null) {
                    records.setDoctor(doctor);
                }
                records.setSystemUser(systemUserService.getCurrentUser());
                records.setCustomer(customer);
            }
        }


    }

    private void alterarSituacao() throws NumberFormatException {

        if (diarywaitinglineid != null) {
            if (diary == null) {
                diary = (diaryService.find(Long.parseLong(diarywaitinglineid)));
                diary.setStatus(false);
                diary.setDiarySituation(DiarySituation.CALL_ENDED);
                diaryService.update(diary);
                waitingLineService.getWaitingLineForProcedure(Long.parseLong(diarywaitinglineid));
            }
        }
    }

    public void getHistoryRecords() {

        recordses = recordsService.getHistoryRecords(customer);
    }

    public void saveAnamnese() {


        if (anamneses == null) {
            anamneses = new ArrayList<Anamnese>();
        }

        if (anamnese.getId() != null) {
            if (!anamneses.contains(anamnese)) {
                anamneses.add(anamnese);
            }
        } else {
            anamneses.add(anamnese);
        }

        records.setAnamneses(anamneses);


        if (records.getId() == null) {
            records.setCreateAt(new Date());
            recordsService.save(records);
        } else {

            recordsService.update(records);
        }

        if (diary != null && diary.getId() != null) {
            diary.setRecords(records);
            diaryService.update(diary);
        }

        tabView.setActiveIndex(2);
        alterarSituacao();


    }

    public void savePhysical() {
        alterarSituacao();

        records.setPhysicalExamination(physicalExamination);

        if (records.getId() == null) {
            recordsService.save(records);
        } else {
            recordsService.update(records);
        }

        if (diary != null && diary.getId() != null) {
            diary.setRecords(records);
            diaryService.update(diary);
        }
        tabView.setActiveIndex(3);
    }

    public void saveDiagnostic() {
        alterarSituacao();

        records.setDiagnostic(diagnostic);

        if (records.getId() == null) {
            records.setCreateAt(new Date());
            recordsService.save(records);
        } else {
            recordsService.update(records);
        }

        if (diary != null && diary.getId() != null) {
            diary.setRecords(records);
            diaryService.update(diary);
        }

        tabView.setActiveIndex(4);

    }

    public void savePrescription() {
        alterarSituacao();

        if (records.getId() == null) {
            records.setCreateAt(new Date());
            recordsService.save(records);
        } else {
            recordsService.update(records);
        }

        if (diary != null && diary.getId() != null) {
            diary.setRecords(records);
            diaryService.update(diary);
        }
        tabView.setActiveIndex(5);
    }

    public void savePreescriptionAndFinaly() {
        alterarSituacao();

        savePrescription();
        Msg.messagemInfo("Prontuário salvo com sucesso !");
        RequestContext.getCurrentInstance().scrollTo("message");
        tabView.setActiveIndex(0);
    }

    public void saveEvolution() {

        alterarSituacao();

        if (evolution.getId() != null) {
            if (!evolutions.contains(evolution)) {
                evolutions.add(evolution);
            }
        } else if ((evolution.getDescr() != null && !evolution.getDescr().isEmpty()) || evolution.getDateEvolution() != null) {
            evolutions.add(evolution);
        }

        records.setEvolutions(evolutions);


        if (records.getId() == null) {
            records.setCreateAt(new Date());
            recordsService.save(records);
        } else {
            System.err.println(evolutions + " - " + evolution);
            recordsService.update(records);
        }

        tabView.setActiveIndex(6);
    }

    public void saveAnnex() {

        alterarSituacao();

        if (records.getAnnexs() == null || records.getAnnexs().isEmpty()) {
            records.setAnnexs(annexs);
        } else {
            records.getAnnexs().addAll(annexs);
        }

        if (records.getId() == null) {
            records.setCreateAt(new Date());
            recordsService.save(records);
            Msg.messagemInfo("Prontuário salvo com sucesso !");
            RequestContext.getCurrentInstance().scrollTo("message");
        } else {
            recordsService.update(records);
            Msg.messagemInfo("Prontuário atualizado com sucesso !");
            RequestContext.getCurrentInstance().scrollTo("message");
        }

        if (diary != null && diary.getId() != null) {
            diary.setRecords(records);
            diaryService.update(diary);
        }
    }

    public void save() {
        alterarSituacao();

        anamneses = new ArrayList<Anamnese>();
        //evolutions.add(evolution);
        //anamneses.add(anamnese);
        if (doctor != null) {
            records.setDoctor(doctor);
        }
        records.setProcedure(procedure);
        records.setCustomer(customer);
        //records.setEvolutions(evolutions);
        //records.setAnamneses(anamneses);
        records.setAnnexs(annexs);
        records.setDiagnostic(diagnostic);
        records.setPhysicalExamination(physicalExamination);

        if (records.getId() == null) {
            records.setCreateAt(new Date());
            recordsService.save(records);
            Msg.messagemInfo("Prontuário salvo com sucesso !");
        } else {
            recordsService.update(records);
            Msg.messagemInfo("Prontuário atualizado com sucesso !");
        }

        if (diary != null && diary.getId() != null) {
            diary.setRecords(records);
            diaryService.update(diary);
        }
    }

    public int getAge() {
        int idade = 0;
        if (customer.getDateBirth() != null) {
            Calendar c = new GregorianCalendar();
            Calendar dateBirth = new GregorianCalendar();
            dateBirth.setTime(customer.getDateBirth());

            idade = c.get(Calendar.YEAR) - dateBirth.get(Calendar.YEAR);

            dateBirth.add(Calendar.YEAR, idade);

            if (c.before(dateBirth)) {
                idade--;
            }
        }
        return idade;

    }

    public Diagnostic getDiagnostic() {
        return diagnostic;
    }

    public void setDiagnostic(Diagnostic diagnostic) {
        this.diagnostic = diagnostic;
    }

    public PhysicalExamination getPhysicalExamination() {
        return physicalExamination;
    }

    public void setPhysicalExamination(PhysicalExamination physicalExamination) {
        this.physicalExamination = physicalExamination;
    }

    public CustomerService getCustomerService() {
        return customerService;
    }

    public void setCustomerService(CustomerService customerService) {
        this.customerService = customerService;
    }

    public Anamnese getAnamnese() {
        return anamnese;
    }

    public void setAnamnese(Anamnese anamnese) {
        this.anamnese = anamnese;
    }

    public Customer getCustomer() {
        return customer;
    }

    public void setCustomer(Customer customer) {
        this.customer = customer;
    }

    public Records getRecords() {
        return records;
    }

    public void setRecords(Records records) {
        this.records = records;
    }

    public void handle(FileUploadEvent event) throws IOException {
        handleAux(event.getFile().getContents(), event.getFile().getFileName(),
                event.getFile().getContentType(), event.getFile().getInputstream());
    }

    private void handleAux(byte[] imageBytes, String nome, String tipo, InputStream is) throws IOException {

        byte[] bytes = null;

        Annex annex = new Annex();
        bytes = imageBytes;
        annex.setType(tipo);
        annex.setDescription(nome);
        if (bytes != null) {
            annex.setFileByte(bytes);
            annexService.save(annex);
            System.err.println("Anexo" + annex);
            annexs.add(annex);
            annex = new Annex();
        }
    }

    public List<Annex> getAnnexs() {
        return annexs;
    }

    public void setAnnexs(List<Annex> annexs) {
        this.annexs = annexs;
    }

    public List<Anamnese> getAnamneses() {
        return anamneses;
    }

    public void setAnamneses(List<Anamnese> anamneses) {
        this.anamneses = anamneses;
    }

    public Evolution getEvolution() {
        return evolution;
    }

    public void setEvolution(Evolution evolution) {
        this.evolution = evolution;
    }

    public List<Evolution> getEvolutions() {
        return evolutions;
    }

    public void setEvolutions(List<Evolution> evolutions) {
        this.evolutions = evolutions;
    }

    public List<Records> getRecordses() {
        return recordses;
    }

    public void setRecordses(List<Records> recordses) {
        this.recordses = recordses;
    }

    public TabView getTabView() {
        return tabView;
    }

    public void setTabView(TabView tabView) {
        this.tabView = tabView;
    }

    public void lastPrescriptionRecords() {
        records.setPrescription(recordsService.getLastPrescriptionRecords(customer));
    }

    public void reportPreescription() {
        if (doctor != null) {
            records.setDoctor(doctor);
        }
        records.setCustomer(customer);
        if (records.getId() == null) {
            records.setCreateAt(new Date());
            recordsService.save(records);
        } else {
            recordsService.update(records);
        }

        recordsService.reportsPrescription(records);
    }
    
    public void reportPreescriptionEspecial() {
        if (doctor != null) {
            records.setDoctor(doctor);
        }
        records.setCustomer(customer);
        if (records.getId() == null) {
            records.setCreateAt(new Date());
            recordsService.save(records);
        } else {
            recordsService.update(records);
        }

        recordsService.reportsPrescriptionEspecial(records);
    }

    public Procedure getProcedure() {
        return procedure;
    }

    public void setProcedure(Procedure procedure) {
        this.procedure = procedure;
    }

    public void pesoIdeal() {
        if (physicalExamination.getHeight() != null) {
            if (customer.getGender() == Gender.MASCULINO) {
                physicalExamination.setPesoIdeal(
                        new BigDecimal(((physicalExamination.getHeight() * 100f) - 100f) - (((physicalExamination.getHeight() * 100f) - 150f) / 4f)));
            } else if (customer.getGender() == Gender.FEMININO) {
                physicalExamination.setPesoIdeal(
                        new BigDecimal(((physicalExamination.getHeight() * 100f) - 100f) - (((physicalExamination.getHeight() * 100f) - 150f) / 2f)));
            }

        }
    }

    public void calcImc() {
        try {
            pesoIdeal();
            calcularVet();
        } catch (Exception e) {
            e.printStackTrace();
        }
        if (physicalExamination.getWeight() != null && physicalExamination.getHeight() != null) {
            physicalExamination.setImc(
                    new BigDecimal(physicalExamination.getWeight()).divide(new BigDecimal(physicalExamination.getHeight()).multiply(new BigDecimal(physicalExamination.getHeight())), 2, RoundingMode.UP));

            float imc = (Float.parseFloat(physicalExamination.getImc().toString()));
            
            
            if (imc < ImcClassificacao.ABAIXO_PESO_IDEAL.getPesoMaximo()) {
                physicalExamination.setImcClassificacao(ImcClassificacao.ABAIXO_PESO_IDEAL);
            } else if (imc >= ImcClassificacao.PESO_NORMAL.getPesoMinimo() && imc < ImcClassificacao.PESO_NORMAL.getPesoMaximo()) {
                physicalExamination.setImcClassificacao(ImcClassificacao.PESO_NORMAL);
            } else if (imc >= ImcClassificacao.EXCESSO_PESO.getPesoMinimo() && imc < ImcClassificacao.EXCESSO_PESO.getPesoMaximo()) {
                physicalExamination.setImcClassificacao(ImcClassificacao.EXCESSO_PESO);
            } else if (imc >= ImcClassificacao.OBESIDADE_I.getPesoMinimo() && imc < ImcClassificacao.OBESIDADE_I.getPesoMaximo()) {
                physicalExamination.setImcClassificacao(ImcClassificacao.OBESIDADE_I);
            } else if (imc >= ImcClassificacao.OBESIDADE_II.getPesoMinimo() && imc < ImcClassificacao.OBESIDADE_II.getPesoMaximo()) {
                physicalExamination.setImcClassificacao(ImcClassificacao.OBESIDADE_II);
            } else if (imc >= ImcClassificacao.OBESIDADE_III.getPesoMinimo() && imc < ImcClassificacao.OBESIDADE_III.getPesoMaximo()) {
                physicalExamination.setImcClassificacao(ImcClassificacao.OBESIDADE_III);
            }

            System.err.println(imc);
        }
    }

    public void calcularVet() {
        try {
            calcularTmb();
            calcularFa();

            if (physicalExamination.getTmb() != null) {
                physicalExamination.setVet(physicalExamination.getTmb().multiply(physicalExamination.getFa()));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void calcularFa() {
        if (physicalExamination.getFatorAtividadeFisica() != null && customer != null && customer.getGender() != null) {
            if (customer.getGender() == Gender.MASCULINO) {
                physicalExamination.setFa(new BigDecimal(physicalExamination.getFatorAtividadeFisica().getMasculino()));
            } else {
                physicalExamination.setFa(new BigDecimal(physicalExamination.getFatorAtividadeFisica().getFeminino()));
            }
        }
    }

    public void calcularTmb() {
        if (physicalExamination.getWeight() != null && customer != null && customer.getGender() != null) {
            float tmb = 0f;
            int age = getAge();
            if (age >= 18 && age <= 29) {
                if (customer.getGender() == Gender.MASCULINO) {
                    tmb = 15.3f * physicalExamination.getWeight() + 679f;
                } else {
                    tmb = 14.7f * physicalExamination.getWeight() + 496;
                }
            } else if (age >= 30 && age <= 60) {
                if (customer.getGender() == Gender.MASCULINO) {
                    tmb = 11.6f * physicalExamination.getWeight() + 879f;
                } else {
                    tmb = 8.7f * physicalExamination.getWeight() + 829;
                }
            }
            if (age > 60) {
                if (customer.getGender() == Gender.MASCULINO) {
                    tmb = 13.5f * physicalExamination.getWeight() + 487f;
                } else {
                    tmb = 10.5f * physicalExamination.getWeight() + 596;
                }
            }

            physicalExamination.setTmb(new BigDecimal(tmb));
        }
    }

    public List<SelectItem> selectFatorAtividadeFisica() {
        List<SelectItem> paymentTypes = new ArrayList<SelectItem>();
        for (FatorAtividadeFisica ms : FatorAtividadeFisica.values()) {
            paymentTypes.add(new SelectItem(ms, ms.getNome()));
        }
        return paymentTypes;
    }

    public String getDiarywaitinglineid() {
        return diarywaitinglineid;
    }

    public void setDiarywaitinglineid(String diarywaitinglineid) {
        this.diarywaitinglineid = diarywaitinglineid;
    }
    
    
}
